home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 / SpriteWorld Examples / Shark Attack / Sources & Headers / Shark Attack.c < prev    next >
Encoding:
Text File  |  1999-01-25  |  13.1 KB  |  484 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. // Shark Attack.c
  3. //
  4. // Created 7/25/96
  5. ///--------------------------------------------------------------------------------------
  6.  
  7.  
  8. #include <SWIncludes.h>
  9. #include <SWGameUtils.h>
  10. #include <SWApplication.h>
  11.  
  12. #include "Application.h"
  13. #include "Shark Attack.h"
  14. #include "Level.h"
  15. #include "NewSprite.h"
  16. #include "MyUtils.h"
  17. #include "Special Effects.h"
  18. #include "Stats.h"
  19.  
  20.  
  21. #define kMaxFPS                    45            // Keep the animation from going too fast
  22.  
  23. #define kMaxSpriteWorldWidth    640            // Max size of the SpriteWorld. Helps avoid
  24. #define kMaxSpriteWorldHeight    480            // running out of memory on large monitors.
  25.  
  26.  
  27. /***********/
  28. /* Globals */
  29. /***********/
  30.  
  31. SpriteWorldPtr    gSpriteWorldP;
  32. FramePtr         gStatsWindowFrameP;
  33. FramePtr         gStatsBackFrameP;
  34. FramePtr         gStatsNumberFrameP;
  35. SpriteLayerPtr    gSubSpriteLayerP;
  36. SpriteLayerPtr    gBulletSpriteLayerP;
  37. SpriteLayerPtr    gFishSpriteLayerP;
  38. SpriteLayerPtr    gSharkSpriteLayerP;
  39. WindowPtr        gWindowP;
  40. RgnHandle        gOrigWindRgn;         // Original region for the window
  41. RgnHandle        gPixPatWindRgn;        // Temporary region for drawing the background pixPat
  42. RgnHandle        gTempRgn;            // Temporary region used by the FishHitDrawProc
  43.  
  44. DrawProcPtr        gScreenDrawProc;
  45. DrawProcPtr        gSpriteMaskDrawProc;
  46. KeyStruct        gKeys;
  47.  
  48. PixPatHandle    gBackgroundPixPatH;
  49. PixPatHandle    gTitleWaterPixPatH;
  50. PicHandle        gGameWaterPictH;
  51.  
  52. short            gFishDelay = 0;
  53. short            gSharkDelay = 0;
  54. short            gNumFishOnScreen = 0;
  55. short            gNumSharksOnScreen = 0;
  56. SpritePtr        gLastBulletP;            // Pointer to the most recently shot bullet. Kept
  57.                                         // so we can update the stereo sound as it moves.
  58. SpritePtr        gSubCloneP = NULL;        // Pointer to the sub sprite that is added
  59.                                         // to the animation. Used by SharkSpriteMoveProc
  60.  
  61. Boolean            gGameOver;
  62. Boolean            gGameIsPaused;
  63. long            gScore;
  64. long            gNextLevelScore;        // When score equals this, advance to next level
  65. short            gCurrentLevel;
  66. short            gNumLivesLeft;
  67. short            gNumShellsNeeded;
  68. Boolean            gSubIsStillOnScreen;
  69.  
  70.  
  71. ///--------------------------------------------------------------------------------------
  72. // SetUpSpriteWorld
  73. ///--------------------------------------------------------------------------------------
  74.  
  75. void    SetUpSpriteWorld( void )
  76. {
  77.     Rect            worldRect;
  78.     OSErr            err;
  79.  
  80.     
  81.     err = SWEnterSpriteWorld();
  82.     FatalError(err);
  83.     
  84.     worldRect = gWindowP->portRect;
  85.     
  86.     if (worldRect.right > kMaxSpriteWorldWidth)
  87.         worldRect.right = kMaxSpriteWorldWidth;
  88.     if (worldRect.bottom > kMaxSpriteWorldHeight)
  89.         worldRect.bottom = kMaxSpriteWorldHeight;
  90.     
  91.     CenterRect(&worldRect, &gWindowP->portRect);
  92.     err = SWCreateSpriteWorldFromWindow(&gSpriteWorldP, (CWindowPtr)gWindowP, 
  93.             &worldRect, NULL, 0);
  94.     FatalError(err);
  95.     
  96.     
  97.         // Create the sprite layers
  98.     err = SWCreateSpriteLayer(&gSubSpriteLayerP);
  99.     FatalError(err);
  100.     
  101.     err = SWCreateSpriteLayer(&gBulletSpriteLayerP);
  102.     FatalError(err);
  103.     
  104.     err = SWCreateSpriteLayer(&gFishSpriteLayerP);
  105.     FatalError(err);
  106.     
  107.     err = SWCreateSpriteLayer(&gSharkSpriteLayerP);
  108.     FatalError(err);
  109.     
  110.     SWAddSpriteLayer(gSpriteWorldP, gFishSpriteLayerP);    // Bottom layer
  111.     SWAddSpriteLayer(gSpriteWorldP, gSharkSpriteLayerP);    // Middle layer
  112.     SWAddSpriteLayer(gSpriteWorldP, gBulletSpriteLayerP);    // Middle layer
  113.     SWAddSpriteLayer(gSpriteWorldP, gSubSpriteLayerP);        // Top layer
  114.     
  115.     SWLockSpriteWorld(gSpriteWorldP);
  116.     
  117.     
  118.         // Draw a nice background
  119.     SWSetPortToBackground(gSpriteWorldP);
  120.     FillCRect(&gSpriteWorldP->backRect, gTitleWaterPixPatH);
  121.  
  122.     
  123.         // Set up the various drawProcs
  124.         
  125.     if (gSpriteWorldP->pixelDepth == 8)        // If in 256 colors
  126.     {
  127.         gScreenDrawProc = BlitPixie8BitRectDrawProc;
  128.         SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
  129.         gSpriteMaskDrawProc = CompiledSprite8BitDrawProc;
  130.     }
  131.     else if ( !(SW_PPC && gSpriteWorldP->pixelDepth < 8) )    // Not 256 colors
  132.     {
  133.         gScreenDrawProc = BlitPixieAllBitRectDrawProc;
  134.         SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
  135.         gSpriteMaskDrawProc = BlitPixieAllBitMaskDrawProc;
  136.     }
  137.     else
  138.     {
  139.         gScreenDrawProc = SWStdWorldDrawProc;
  140.         gSpriteMaskDrawProc = SWStdSpriteDrawProc;
  141.     }
  142.     
  143.     SWSetSpriteWorldMaxFPS(gSpriteWorldP, kMaxFPS);
  144. }
  145.  
  146.  
  147. ///--------------------------------------------------------------------------------------
  148. // NewGame - called when the user selects "New Game" from the File Menu.
  149. ///--------------------------------------------------------------------------------------
  150.  
  151. void    NewGame( void )
  152. {
  153.     PrepareGame();
  154.     RunGame();
  155.     CleanUpAfterGame();
  156. }
  157.  
  158.  
  159. ///--------------------------------------------------------------------------------------
  160. // PrepareGame
  161. ///--------------------------------------------------------------------------------------
  162.  
  163. void    PrepareGame( void )
  164. {
  165.     Rect    worldRect;
  166.     
  167.     gLastBulletP = NULL;
  168.     gGameOver = false;
  169.     gCurrentLevel = 1;
  170.     gNumLivesLeft = 3;
  171.     gNumShellsNeeded = 10;
  172.     gScore = 0;
  173.     gNextLevelScore = kAdvanceLevelScore;
  174.     
  175.     ResetStats();
  176.     HideCursor();
  177.     EraseMenuBar();
  178.     
  179.         // We can draw directly to the screen now
  180.     SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, gScreenDrawProc);
  181.     
  182.         // Remove sprites from title screen animation
  183.     RemoveAllSprites(gSpriteWorldP);
  184.  
  185.         // Make the SpriteWorld think it's smaller, to make room for the stats area
  186.     worldRect = gSpriteWorldP->windRect;
  187.     worldRect.top += kStatsHeight;
  188.     SWChangeWorldRect(gSpriteWorldP, &worldRect, true);
  189.     
  190.         // Draw the game background
  191.     FillBackgroundWithPict(gSpriteWorldP, gGameWaterPictH);
  192.     
  193.     SetUpLevel();
  194.     SWUpdateSpriteWorld(gSpriteWorldP, false);
  195.     WipeWindow(gSpriteWorldP);
  196.     
  197.         // Draw the stats area
  198.     UpdateStatsArea();
  199. }
  200.  
  201.  
  202. ///--------------------------------------------------------------------------------------
  203. // EraseMenuBar - hide menu bar and draw background pixpat in its place, if necessary.
  204. ///--------------------------------------------------------------------------------------
  205.  
  206. void    EraseMenuBar( void )
  207. {
  208.     RgnHandle mBarRgn;
  209.     
  210.     SetPort(gWindowP);
  211.     mBarRgn = SWHideMenuBar(gWindowP);
  212.     
  213.         // mBarRgn = mBarRgn & gPixPatWindRgn
  214.     SectRgn(mBarRgn, gPixPatWindRgn, mBarRgn);
  215.     
  216.     SetClip(mBarRgn);
  217.     FillCRect(&gWindowP->portRect, gBackgroundPixPatH);
  218.     SetClip(gOrigWindRgn);
  219. }
  220.  
  221.  
  222. ///--------------------------------------------------------------------------------------
  223. // RunGame
  224. ///--------------------------------------------------------------------------------------
  225.  
  226. void    RunGame( void )
  227. {
  228.     FatalError( SWStickyError() ); // Make sure no errors got past us during setup
  229.  
  230.     while (!gGameOver)
  231.     {
  232.         SWProcessSpriteWorld(gSpriteWorldP);
  233.         
  234.             // Check for collisions with the fish and bullets
  235.         SWCollideSpriteLayer(gSpriteWorldP, gFishSpriteLayerP, gBulletSpriteLayerP);
  236.         SWCollideSpriteLayer(gSpriteWorldP, gSharkSpriteLayerP, gBulletSpriteLayerP);
  237.  
  238.             // Make sure no errors occurred during a MoveProc, etc.
  239.         FatalError( SWStickyError() );
  240.         
  241.         SWAnimateSpriteWorld(gSpriteWorldP);
  242.         
  243.         if (gSpriteWorldP->frameHasOccurred)
  244.             ProcessLevel();
  245.         
  246.             // Check for collisions with the submarine and fish
  247.         SWCollideSpriteLayer(gSpriteWorldP, gSubSpriteLayerP, gFishSpriteLayerP);
  248.         SWCollideSpriteLayer(gSpriteWorldP, gSubSpriteLayerP, gSharkSpriteLayerP);
  249.         
  250.         UpdateKeys();    // Read any new keyUp/keyDown events
  251.         UpdateStatsNumbers();
  252.         
  253.             // Time to advance the level?
  254.         if (gScore > gNextLevelScore && gNumFishOnScreen == 0 && gNumSharksOnScreen == 0)
  255.             AdvanceLevel();
  256.     }
  257. }
  258.  
  259.  
  260. ///--------------------------------------------------------------------------------------
  261. // CleanUpAfterGame
  262. ///--------------------------------------------------------------------------------------
  263.  
  264. void    CleanUpAfterGame( void )
  265. {
  266.         // Remove any sprites that are left
  267.     RemoveAllSprites(gSpriteWorldP);
  268.     
  269.         // Restore the SpriteWorld to its normal size
  270.     SWRestoreWorldRect(gSpriteWorldP);
  271.     
  272.         // Draw the normal background pattern
  273.     SWSetPortToBackground(gSpriteWorldP);
  274.     FillCRect(&gSpriteWorldP->backRect, gTitleWaterPixPatH);
  275.     
  276.     AddTitleSprite();
  277.     SWUpdateSpriteWorld(gSpriteWorldP, false);
  278.     WipeWindow(gSpriteWorldP);
  279.     
  280.         // Don't draw directly to the screen during the title screen animation
  281.     SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, SWStdWorldDrawProc);
  282.     
  283.     gFishDelay = 0;
  284.     gSharkDelay = 0;
  285.  
  286.     
  287.     SWShowMenuBar(gWindowP);
  288.     ShowCursor();
  289. }
  290.  
  291.  
  292. ///--------------------------------------------------------------------------------------
  293. // RemoveAllSprites - Remove and dispose all sprites in the SpriteWorld
  294. ///--------------------------------------------------------------------------------------
  295.  
  296. void    RemoveAllSprites(SpriteWorldPtr spriteWorldP)
  297. {
  298.     SpriteLayerPtr    curSpriteLayerP;
  299.     SpritePtr        curSpriteP, nextSpriteP;
  300.     
  301.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  302.     
  303.         // iterate through the layers in the world
  304.     while (curSpriteLayerP != NULL)
  305.     {
  306.         curSpriteP = curSpriteLayerP->headSpriteP;
  307.         
  308.             // iterate through the sprites in this layer
  309.         while (curSpriteP != NULL)
  310.         {            
  311.             nextSpriteP = curSpriteP->nextSpriteP;
  312.             
  313.             SWRemoveSprite(curSpriteP);
  314.             SWDisposeSprite(&curSpriteP);
  315.             
  316.             curSpriteP = nextSpriteP;
  317.         }
  318.         
  319.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  320.     }
  321.     
  322.     gNumFishOnScreen = 0;
  323.     gNumSharksOnScreen = 0;
  324.     gLastBulletP = NULL;
  325. }
  326.  
  327.  
  328. ///--------------------------------------------------------------------------------------
  329. // PauseSprites - Pause all layers but the sub layer
  330. ///--------------------------------------------------------------------------------------
  331.  
  332. void    PauseSprites()
  333. {
  334.     SWPauseSpriteLayer(gBulletSpriteLayerP);
  335.     SWPauseSpriteLayer(gFishSpriteLayerP);
  336.     SWPauseSpriteLayer(gSharkSpriteLayerP);
  337. }
  338.  
  339.  
  340. ///--------------------------------------------------------------------------------------
  341. // UnpauseSprites - unpause all layers but the sub layer
  342. ///--------------------------------------------------------------------------------------
  343.  
  344. void    UnpauseSprites()
  345. {
  346.     SWUnpauseSpriteLayer(gBulletSpriteLayerP);
  347.     SWUnpauseSpriteLayer(gFishSpriteLayerP);
  348.     SWUnpauseSpriteLayer(gSharkSpriteLayerP);
  349. }
  350.  
  351.  
  352. ///--------------------------------------------------------------------------------------
  353. // CountNumSpritesOnScreen - returns how many Sprites are currently on the screen
  354. ///--------------------------------------------------------------------------------------
  355.  
  356. short    CountNumSpritesOnScreen(SpriteWorldPtr spriteWorldP)
  357. {
  358.     SpriteLayerPtr    curSpriteLayerP;
  359.     short                numSprites = 0;
  360.     
  361.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  362.     
  363.         // iterate through the layers in the world
  364.     while (curSpriteLayerP != NULL)
  365.     {
  366.         numSprites += SWCountNumSpritesInLayer(curSpriteLayerP);
  367.         
  368.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  369.     }
  370.     
  371.     return numSprites;
  372. }
  373.  
  374.  
  375. ///--------------------------------------------------------------------------------------
  376. //  UpdateKeys (Put the latest key values in the gKeys structure)
  377. ///--------------------------------------------------------------------------------------
  378.  
  379. void    UpdateKeys( void )
  380. {
  381.     EventRecord        event;
  382.     short            theChar;
  383.     
  384.     do
  385.     {
  386.         GetOSEvent( (keyUpMask | keyDownMask), &event );
  387.         ProcessKeyEvent(&event);
  388.         
  389.             // Check for shift key
  390.         if (event.modifiers & shiftKey)
  391.             gKeys.shift = true;
  392.         else
  393.             gKeys.shift = false;
  394.         
  395.             // Check for Command key combinations
  396.         if ((event.modifiers & cmdKey) && (event.what == keyDown))
  397.         {
  398.             theChar = event.message & charCodeMask;
  399.             
  400.             if (theChar == 'p')
  401.                 PauseGame();
  402.             else if (theChar == 'e')
  403.                 gGameOver = true;
  404.             else if (theChar == 'q')
  405.                 ExitSharkAttack();
  406.         }
  407.         
  408.     } while (event.what != nullEvent);
  409. }
  410.  
  411.  
  412. ///--------------------------------------------------------------------------------------
  413. // ProcessKeyEvent
  414. ///--------------------------------------------------------------------------------------
  415.  
  416. void    ProcessKeyEvent( EventRecord *eventP )
  417. {
  418.     short            theKey;
  419.     Boolean            keyState;
  420.     
  421.     if (eventP->what == keyUp || eventP->what == keyDown)
  422.     {
  423.         theKey = (eventP->message & keyCodeMask) >> 8;
  424.         keyState = (eventP->what == keyDown);
  425.         
  426.         if ( (theKey == kLeftArrowKey) || (theKey == kLeftKeyPad) )
  427.             gKeys.left = keyState;
  428.         if ( (theKey == kRightArrowKey) || (theKey == kRightKeyPad) )
  429.             gKeys.right = keyState;
  430.         if ( (theKey == kDownArrowKey) || (theKey == kDownKeyPad) )
  431.             gKeys.down = keyState;
  432.         if ( (theKey == kUpArrowKey) || (theKey == kUpKeyPad) )
  433.             gKeys.up = keyState;
  434.         if (theKey == kShootKeyPad)
  435.             gKeys.shoot = keyState;
  436.         if (theKey == kEscKey && eventP->what == keyDown)
  437.             gGameOver = true;
  438.     }
  439. }
  440.  
  441.  
  442. ///--------------------------------------------------------------------------------------
  443. // PauseGame
  444. ///--------------------------------------------------------------------------------------
  445.  
  446. void    PauseGame( void )
  447. {
  448.     MenuHandle        fileMenuH;
  449.     
  450.     fileMenuH = GetMenuHandle(mFile);
  451.     CheckItem(fileMenuH, iPauseGame, true);
  452.     EnableItem(fileMenuH, iPauseGame);
  453.     EnableItem(fileMenuH, iEndGame);
  454.     DisableItem(fileMenuH, iNewGame);
  455.     
  456.     SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, SWStdWorldDrawProc);
  457.     SWSetPortToWorkArea(gSpriteWorldP);
  458.     ForeColor(redColor);
  459.     DrawTextInWorkArea("\pPaused", 64);
  460.     SWUpdateWindow(gSpriteWorldP);
  461.     
  462.     HiliteMenu( 0 );
  463.     SWShowMenuBar(gWindowP);
  464.     ShowCursor();
  465.     
  466.     gGameIsPaused = true;
  467.     
  468.     while (gGameIsPaused)
  469.         ProcessEvents();
  470.     
  471.     CheckItem(fileMenuH, iPauseGame, false);
  472.     DisableItem(fileMenuH, iPauseGame);
  473.     DisableItem(fileMenuH, iEndGame);
  474.     EnableItem(fileMenuH, iNewGame);
  475.     
  476.     EraseMenuBar();
  477.     HideCursor();
  478.     UpdateStatsArea();
  479.     SWUpdateSpriteWorld(gSpriteWorldP, true);
  480.     SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, gScreenDrawProc);
  481. }
  482.  
  483.  
  484.